"""
Authentication routes for LandPPT using Supertokens
"""

from fastapi import APIRouter, Request, Form, Depends, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
import logging

from supertokens_python.recipe.session.framework.fastapi import verify_session
from supertokens_python.recipe.session.interfaces import SessionContainer
from supertokens_python.recipe.session import SessionRecipe
from supertokens_python.recipe.session.syncio import create_new_session, get_session, revoke_session

from .auth_service import get_auth_service, AuthService
from .middleware import get_current_user_optional, get_current_user_required
from ..database.database import get_db
from ..database.models import User
from ..core.config import app_config

logger = logging.getLogger(__name__)

router = APIRouter()
templates = Jinja2Templates(directory="src/landppt/web/templates")

# Helper function to create context processor for templates
def get_template_context(request: Request):
    """Get additional template context including url_for function"""
    root_path = request.scope.get("root_path", "")
    
    def url_for(path: str):
        """Generate URL with proper root_path prefix"""
        if not path.startswith("/"):
            path = f"/{path}"
        if root_path and not path.startswith(root_path):
            return f"{root_path}{path}"
        return path
    
    return {"url_for": url_for, "root_path": root_path}

def render_template(template_name: str, request: Request, context: dict = None):
    """Helper function to render template with proper context"""
    if context is None:
        context = {}
    
    # Always include request
    context["request"] = request
    
    # Add template context (url_for, root_path, etc.)
    context.update(get_template_context(request))
    
    return templates.TemplateResponse(template_name, context)


@router.get("/auth/login", response_class=HTMLResponse)
async def login_page(
    request: Request,
    error: str = None,
    success: str = None,
    username: str = None,
    db: Session = Depends(get_db)
):
    """Login page"""
    # Check if user is already logged in
    user = get_current_user_optional(request, db)
    if user:
        return RedirectResponse(url="/dashboard", status_code=302)
    
    return render_template("login.html", request, {
        "error": error,
        "success": success,
        "username": username
    })


@router.post("/auth/login")
async def login(
    request: Request,
    username: str = Form(...),
    password: str = Form(...),
    db: Session = Depends(get_db),
    auth_service: AuthService = Depends(get_auth_service)
):
    """Handle login form submission"""
    try:
        # Authenticate user
        user = auth_service.authenticate_user(db, username, password)
        
        if not user:
            return render_template("login.html", request, {
                "error": "用户名或密码错误",
                "username": username
            })
        
        # Create Supertokens session
        session = create_new_session(request, str(user.id))
        
        # Redirect to dashboard
        response = RedirectResponse(url="/dashboard", status_code=302)
        
        logger.info(f"User {username} logged in successfully")
        return response
        
    except Exception as e:
        logger.error(f"Login error: {e}")
        return render_template("login.html", request, {
            "error": "登录过程中发生错误，请重试",
            "username": username
        })


@router.get("/auth/logout")
async def logout(
    request: Request,
    session: SessionContainer = Depends(verify_session(session_required=False))
):
    """Logout user"""
    if session:
        await revoke_session(session.get_handle())
    
    response = RedirectResponse(url="/auth/login?success=已成功退出登录", status_code=302)
    return response


@router.get("/auth/profile", response_class=HTMLResponse)
async def profile_page(
    request: Request,
    user: User = Depends(get_current_user_required)
):
    """User profile page"""
    return render_template("profile.html", request, {
        "user": user.to_dict()
    })


@router.post("/auth/change-password")
async def change_password(
    request: Request,
    current_password: str = Form(...),
    new_password: str = Form(...),
    confirm_password: str = Form(...),
    user: User = Depends(get_current_user_required),
    db: Session = Depends(get_db),
    auth_service: AuthService = Depends(get_auth_service)
):
    """Change user password"""
    try:
        # Validate current password
        if not user.check_password(current_password):
            return render_template("profile.html", request, {
                "user": user.to_dict(),
                "error": "当前密码错误"
            })
        
        # Validate new password
        if new_password != confirm_password:
            return render_template("profile.html", request, {
                "user": user.to_dict(),
                "error": "新密码和确认密码不匹配"
            })
        
        if len(new_password) < 6:
            return render_template("profile.html", request, {
                "user": user.to_dict(),
                "error": "密码长度至少6位"
            })
        
        # Update password
        if auth_service.update_user_password(db, user, new_password):
            return render_template("profile.html", request, {
                "user": user.to_dict(),
                "success": "密码修改成功"
            })
        else:
            return render_template("profile.html", request, {
                "user": user.to_dict(),
                "error": "密码修改失败，请重试"
            })
            
    except Exception as e:
        logger.error(f"Change password error: {e}")
        return render_template("profile.html", request, {
             "user": user.to_dict(),
            "error": "修改密码过程中发生错误"
        })


# API endpoints for authentication
@router.post("/api/auth/login")
async def api_login(
    request: Request,
    username: str = Form(...),
    password: str = Form(...),
    db: Session = Depends(get_db),
    auth_service: AuthService = Depends(get_auth_service)
):
    """API login endpoint"""
    user = auth_service.authenticate_user(db, username, password)
    
    if not user:
        raise HTTPException(status_code=401, detail="用户名或密码错误")
    
    session = create_new_session(request, str(user.id))
    
    return {
        "success": True,
        "user": user.to_dict()
    }


@router.post("/api/auth/logout")
async def api_logout(
    request: Request,
    session: SessionContainer = Depends(verify_session(session_required=False))
):
    """API logout endpoint"""
    if session:
        await revoke_session(session.get_handle())
    
    return {"success": True, "message": "已成功退出登录"}


@router.get("/api/auth/me")
async def api_current_user(
    user: User = Depends(get_current_user_required)
):
    """Get current user info"""
    return {
        "success": True,
        "user": user.to_dict()
    }


@router.get("/api/auth/check")
async def api_check_auth(
    request: Request,
    db: Session = Depends(get_db)
):
    """Check authentication status"""
    user = get_current_user_optional(request, db)
    
    return {
        "authenticated": user is not None,
        "user": user.to_dict() if user else None
    }
